package object2;

/**
 * super关键字
 *  super.属性名
 *  super.方法名(参数列表)
 *  super(参数列表)
 */
public class Super extends Base{

    //4个属性
    public int n1 = 100;

    protected int n2 = 200;

    int n3 = 300;

    private int n4 = 400;

    public Super() {

    }

    public Super(String name) {

    }

    public Super(String name, int n2) {

    }

    public void test100() {

    }

    protected void test200() {

    }

    void test300() {

    }

    private void test400() {

    }

     public void cal(){
        System.out.println("Super类的cal()方法...");
     }
}

class Test extends Super {

    public int n1 = 888;

    public void test() {
        //super的访问不限于直接父类，如果爷爷类和本类中有同名的成员，也可以用super去访问爷爷类的成员
        //如果多个基类(上级类)中都有同名的成员，使用super访问遵循就近原则
        System.out.println("super.n1=" + super.n1);
        super.cal();
    }

    //访问父类的属性，但不能访问父类的private属性 super.属性名
    public void hi() {
        System.out.println(super.n1 + " " + super.n2 + " " + super.n3);
    }

//    public void cal(){
//        System.out.println("Test的cal()方法");
//    }

    public void sum() {

        System.out.println("Test类的sum()");
        //希望调用父类的cal()方法
        //这时，因为子类没有cal()方法，则一直向父类寻找直到Object
        /*
            1)找cal()时，先找本类如果有则调用
            2)如果没有，则找父类（如果有，并可以调用则调用）
            3)如果父类没有，则继续找父类的父类，以此类推直到Object类
            4)如果在查找的过程中找到了但是无法访问则报错
         */
        super.cal();

        /*
            访问属性的规则
            n1 和 this.n1查找的规则：
            1)先找本类，如果有，则调用
            2)如果没有，则找父类（如果有，并可以调用，则调用）
            3)如果父类没有，则继续找父类的父类，以此类推直到Object
            4)如果在查找的过程中找到了但是无法访问则报错
         */
        System.out.println(n1);//888
        System.out.println(this.n1);//888
        System.out.println(super.n1);//100
    }

    //访问父类的方法，不能访问父类的private方法 super.方法名(参数列表)
    public void ok() {
        super.test100();
        super.test200();
        super.test300();
    }

    //访问父类的构造器，只能出现在构造器的第一句，且只能出现一句
    public Test() {
        super("jack");
    }

}